package com.tool.cn.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 时间工具类
 * 
 * @author wangzh
 * 2018年1月2日 下午3:26:36
 */
public final class DateUtil {
	
	private static final Logger log= LoggerFactory.getLogger(DateUtil.class);
	
	private static String formatStr="yyyyMMddHHmmss";
	
	/**
	 * 时间格式效验
	 * @param time 时间字符串
	 * @param formatStr 时间正则
	 * @return
	 */
	public static boolean checkTimeFormat(String time,String formatStr) {
		
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr); 
		sdf.setLenient(false);
		try {
			sdf.parse(time);
			return true;
		} catch (Exception e) {
			log.error("Check Time "+time+" Format Of "+formatStr+" Error",e);
			return false;
		}
	}

	/**
	 * 秒级时间戳转时间 yyyy-MM-dd HH:mm:ss
	 * yyyy-MM-dd'T'HH:mm'Z'
	 */
	public static String UTCTodate(String time) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		int zero = 13 - time.length();
		for (int i = 0; i < zero; i++) {
			time += "0";
		}
		return sdf.format(new Date(Long.parseLong(time)));
	}
	
	/**
	 * 时间转秒级时间戳 yyyy-MM-dd HH:mm:ss
	 * @param datetime
	 * @return
	 */
	public static String dateToUTC(String datetime){
		Date date = null;
		try {
			date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(datetime);
		} catch (ParseException e) {
			log.error(datetime+" Chage To Time Error",e);
			return "";
		}
		return String.valueOf(date.getTime()/1000);
	}
	
	/**
	 * 获取当前秒级UTC时间
	 * @return
	 */
	public static Long dateToUTC(){
		return System.currentTimeMillis()/1000;
	}
	
	/**
	 * 毫秒时间戳转时间
	 */
	public static String getDataDetail(String time) {
		String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(time);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
	}


	/**
	 * 时间转换毫秒时间戳
	 */
	public static String formatStrToDayFirstSec(String time) {
		 String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date=null;
		try {
			date = simpleDateFormat.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
		}
        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
	}
	

	/**
	 * 获取时间
	 * @param time
	 * @return
	 */
	public static long formatStr(String time) {
		long d = 0;
		String f = "yyyyMMddHHmmss";
		switch (time.length()) {
		case 4:
			f = "yyyy";
			break;
		case 6:
			f = "yyyyMM";
			break;
		case 8:
			f = "yyyyMMdd";
			break;
		case 10:
			f = "yyyyMMddHH";
			break;
		case 12:
			f = "yyyyMMddHHmm";
			break;
		default:
			f = "yyyyMMddHHmmss";
		}
		SimpleDateFormat fmt = new SimpleDateFormat(f);
		try {
			Date dt = fmt.parse(time);
			d = dt.getTime() / 1000;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return d;
	}

	/**
	 * 获取当前时间
	 */
	public static String getTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // yyyy-mm-dd
																	// hh:mm:ss
		return sdf.format(new Date());
	}
	
	/**
	 * 获取当前时间
	 * @param format
	 * @return
	 */
	public static String getTime(String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format); 
		return sdf.format(new Date());
	}
	
	public static String getTime(Date date){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); 
		return sdf.format(date); 
	}

	/**
	 * 得到几天前的时间
	 * day 正数 加几天  负数 减几天
	 */
	public static Date getDateBefore(Date date, int day) {
		Calendar now = Calendar.getInstance();
		now.setTime(date);
		now.set(Calendar.DATE, now.get(Calendar.DATE)+day);
		return now.getTime();
	}

	/**
	 * 得到年
	 */
	public static Date getYearBefore(Date date, int year) {
		Calendar now = Calendar.getInstance();
		now.setTime(date);
		now.add(Calendar.YEAR, year);
		return now.getTime();
	}

	/**
	 * 得到月
	 */
	public static Date getMonthBefore(Date date, int month) {
		Calendar now = Calendar.getInstance();
		now.setTime(date);
		now.add(Calendar.MONTH, month);
		return now.getTime();
	}
	
	/**
	 * 获取月第一天
	 * @param date
	 * @return
	 */
	public static Date getFirstDayOfMonth(Date date){
	        Calendar cal = Calendar.getInstance();
	        cal.setTime(date);
	        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
	        cal.set(Calendar.DAY_OF_MONTH, firstDay);
	        return cal.getTime();
	}
	
	/**
	 * 获取月最后一天
	 * @param date
	 * @return
	 */
	public static Date getLastDayOfMonth(Date date){
	        Calendar cal = Calendar.getInstance();
	        cal.setTime(date);
	        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
	        cal.set(Calendar.DAY_OF_MONTH, lastDay);
	        return cal.getTime();
	}
	
	/**
	 * 判断是不是周六日
	 */
	public static boolean isWeek(Date date) {
		if(isSaturday(date)||isSunday(date)){
			return true;
		}
		return false;
		
	}
	
	/**
	 * 判断周六
	 */
	public static boolean isSaturday(Date date){
		Calendar cal=Calendar.getInstance();
		cal.setTime(date);
		if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){  
		    return true;
		}
		return false;
	}
	
	/**
	 * 判断周末
	 */
	public static boolean isSunday(Date date){
		Calendar cal=Calendar.getInstance();
		cal.setTime(date);
		if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){  
		    return true;  
		}  
		return false;
	}
	
	/**
	 * 获取当前时间周一到周五日期
	 */
	public static List <String> getSearchTime(){
		  List<String> searchTime=new ArrayList<String>();
		  Date date=new Date();
		  while(true){
			  if(isWeek(date)){
				  date=getDateBefore(date, -1);
			  }else{
				  searchTime.add(getTime(date));
				  date=getDateBefore(date, -1);
			  }
			  
			  if(searchTime.size()==5){
				  break;
			  }
		  }
		  
		  return searchTime;
	}
	
	/**
	 * 效验时间是否为制定格式
	 */
	public static boolean isValidDate(String str) {
        boolean convertSuccess = true;
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        try {
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }
        return convertSuccess;
    }
	
	/**
	 * 判断是否为周五
	 */
	public static boolean getFive(){
        Calendar c=Calendar.getInstance();
        int weekday=c.get(Calendar.DAY_OF_WEEK);  //6 周五 ，1周日，2周一，3周二，4周三，5周四，7周六
        if(weekday==6){
        	return true;
        }
        System.out.println(weekday);
        return false;
	}
	
	/**
	 * 时间戳转16进制
	 * @param time 必须为long类型
	 * @return
	 */
	public static String formatTime(Long time){
		return String.format("%08X", time);
	}
	
	public static void timeSubtract() {
		String dateStart = "2021-08-19 09:29:58";
        String dateStop = "2021-08-20 10:31:59";

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date d1 = null;
        Date d2 = null;

        try {
            d1 = format.parse(dateStart);
            d2 = format.parse(dateStop);

            //毫秒ms
            long diff = d2.getTime() - d1.getTime();

            long diffSeconds = diff / 1000 % 60;
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;
            long diffDays = diff / (24 * 60 * 60 * 1000);


           System.out.print("两个时间相差：");
            System.out.print(diffDays + " 天, ");
            System.out.print(diffHours + " 小时, ");
            System.out.print(diffMinutes + " 分钟, ");
            System.out.print(diffSeconds + " 秒.");
            System.out.println();
            
            long value=diff/ (60*60 * 1000);
            System.out.println("相差小时"+value);

        } catch (Exception e) {
            e.printStackTrace();
        }
	}
	
	/**
	 * 传入时间与当前时间相差几个小时
	 * @param time yyyyMMddHHmmss 格式时间
	 * @return
	 */
	public static long subtractHour(String time) {
		return subtract(time, 60*60 * 1000,formatStr);
	}
	
	/**
	 * 传入时间与当前时间相差几个小时
	 * @param time 格式时间
	 * @param format  时间格式
	 * @return
	 */
	public static long subtractHour(String time,String format) {
		return subtract(time, 60*60 * 1000,format);
	}
	
	/**
	 * 时间与当前时间相差几天，余出小时时间不算
	 *  @param time yyyyMMddHHmmss 格式时间
	 * @return
	 */
	public static long subtractDay(String time) {
        return subtract(time, 24*60*60 * 1000,formatStr);
	}
	
	/**
	 * 时间与当前时间相差几天，余出小时时间不算
	 *  @param time yyyyMMddHHmmss 格式时间
	 * @param format  时间格式 
	 * @return
	 */
	public static long subtractDay(String time,String format) {
        return subtract(time, 24*60*60 * 1000,format);
	}
	
	/**
	 * 时间与当前时间相差几分钟
	 *  @param time yyyyMMddHHmmss 格式时间
	 * @return
	 */
	public static long subtractMinute(String time) {
        return subtract(time, 60 * 1000,formatStr);
	}
	
	/**
	 * 时间与当前时间相差几分钟
	 *  @param time yyyyMMddHHmmss 格式时间
	 * @param format  时间格式 
	 * @return
	 */
	public static long subtractMinute(String time,String format) {
        return subtract(time, 60 * 1000,format);
	}
	
	/**
	 * 时间与当前时间相差几秒
	 *  @param time yyyyMMddHHmmss 格式时间
	 * @return
	 */
	public static long subtractSecond(String time) {
        return subtract(time, 1000,formatStr);
	}
	
	/**
	 * 时间与当前时间相差几秒
	 *  @param time yyyyMMddHHmmss 格式时间
	 * @param format  时间格式 
	 * @return
	 */
	public static long subtractSecond(String time,String format) {
        return subtract(time, 1000,format);
	}
	
	private static long subtract(String time,long num,String format) {
		
		SimpleDateFormat sdf= new SimpleDateFormat(format);
        try {
        	Date d1 = sdf.parse(time);

            return (System.currentTimeMillis() - d1.getTime())/ num;

        } catch (Exception e) {
        	log.error("Default Format"+formatStr+" Deal "+time+" Error "+e.toString(),e);
        	return -1;
        }
	}
	
	/**
	 * 开始时间与结束时间相差秒数
	 * @param start
	 * @param end
	 * @return
	 */
	public static long subtractSecond(Date start,Date end) {
		return (start.getTime()-end.getTime())/1000;
	}
}
